﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using BLL;
using DLL;
using Core;
using CommonHelpers;
using Printing;
using System.Drawing;
using System.Configuration;
using Logging;
using System.ComponentModel;

namespace QuanLyBanLe
{
    public partial class FormOrder
    {
        private BillService m_BillService;
        private BillDetailService m_BillDetailService;

        private IList<Producer> m_Producers;
        private IList<ProductType> m_ProductTypes;
        private IList<Product> m_Products;

        private bool m_EnableProductTypeChangedEvent;
        private bool m_EnableProducerChangedEvent;
        private bool m_EnableProductChangedEvent;

        private bool m_BillTableDataChanged;
        private Bill m_currentBill;

        private bool m_EnableEvent;
        private PrintDGV printing;

        List<Bill> m_ActiveBills;

        private void InitOrderMan()
        {
            EnableEvents(false);

            m_BillService = new BillService();
            m_BillDetailService = new BillDetailService();

            m_Products = m_ProductService.GetProducts();
            Product allProduct = new Product();
            allProduct.Id = 0;
            allProduct.Name = "Tất cả";
            m_Products.Insert(0, allProduct);
        }

        private void LoadOrderMan()
        {
            colProducer.DataSource = m_Producers;
            colProducer.ValueMember = "Id";
            colProducer.DisplayMember = "Name";

            colProductType.DataSource = m_ProductTypes;
            colProductType.ValueMember = "Id";
            colProductType.DisplayMember = "Name";

            colProduct.DataSource = m_Products;
            colProduct.ValueMember = "Id";
            colProduct.DisplayMember = "Name";

            m_ActiveBills = GetActiveBills();
            cboKhachHang.DataSource = m_ActiveBills;
            cboKhachHang.ValueMember = "Id";
            cboKhachHang.DisplayMember = "TotalMoney";

            dtgBillDetail.AutoGenerateColumns = false;

            if (cboKhachHang.Items.Count > 1) // 0 is empty bill
            {
                int billId = m_ActiveBills[1].Id;
                ShowBillDetail(billId);
                cboKhachHang.SelectedIndex = 1;
                btnDeleteBill.Enabled = true;
                btnPrintBill.Enabled = true;
                btnSaveBill.Enabled = true;
                btnCreateBill.Enabled = true;
                dtgBillDetail.Select();
            }
            else
            {
                CreateNewBill();
            }

            //Setup print
            SetUpPrint();
            EnableEvents(true);
        }

        #region Events

        #region dtgDetail Events
        private void dtgBillDetail_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
        {
            if (e.Control is ComboBox)
            {
                ComboBox cbo = e.Control as ComboBox;
                int currentColumnIndex = dtgBillDetail.CurrentCell.ColumnIndex;
                SetupAutoCompleteDropdownInGrid(cbo);
                if (currentColumnIndex == dtgBillDetail.Columns["colProduct"].Index)
                {
                    // To avoid register twice, remove handler before register
                    cbo.SelectedIndexChanged -= new EventHandler(cboProduct_SelectedIndexChanged);
                    cbo.SelectedIndexChanged += new EventHandler(cboProduct_SelectedIndexChanged);
                }
            }

            // TODO: check needed?
            if (dtgBillDetail.CurrentCell.ColumnIndex == dtgBillDetail.Columns["colBarcode"].Index)
            {
                if (e.Control is DataGridViewTextBoxEditingControl)
                {
                    // Select to the barcode text column so that user can use barcode reader to fill barcode
                    e.Control.Select();
                }
            }

            if (dtgBillDetail.CurrentCell.ColumnIndex == dtgBillDetail.Columns["colBarcode"].Index ||
                dtgBillDetail.CurrentCell.ColumnIndex == dtgBillDetail.Columns["colAmount"].Index ||
                dtgBillDetail.CurrentCell.ColumnIndex == dtgBillDetail.Columns["colPrice"].Index ||
                dtgBillDetail.CurrentCell.ColumnIndex == dtgBillDetail.Columns["colDiscount"].Index ||
                dtgBillDetail.CurrentCell.ColumnIndex == dtgBillDetail.Columns["colWarrantyTime"].Index
                )
            {
                TextBox item = e.Control as TextBox;
                if (item != null)
                {
                    item.KeyPress += new KeyPressEventHandler(item_KeyPress);
                }
            }
        }

        private void item_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (!char.IsControl(e.KeyChar)
                && !char.IsDigit(e.KeyChar))
            {
                e.Handled = true;
            }
        }

        private void dtgBillDetail_DefaultValuesNeeded(object sender, DataGridViewRowEventArgs e)
        {
            // set defaut value for dropdown columns in grid
            e.Row.Cells["colProductType"].Value = 0;
            e.Row.Cells["colProducer"].Value = 0;
            e.Row.Cells["colProduct"].Value = 0;
            e.Row.Cells["colDiscount"].Value = 0;
            e.Row.Cells["colAmount"].Value = 0;
            e.Row.Cells["colPrice"].Value = 0;
            e.Row.Cells["colWarrantyTime"].Value = 0;
        }

        private void dtgBillDetail_CellBeginEdit(object sender, DataGridViewCellCancelEventArgs e)
        {
            // Filter products by product type and producer
            if (e.ColumnIndex == dtgBillDetail.Columns["colProduct"].Index)
            {
                var cellProductType = dtgBillDetail.Rows[e.RowIndex].Cells["colProductType"];
                var cellProducer = dtgBillDetail.Rows[e.RowIndex].Cells["colProducer"];
                if (cellProductType.Value != null && cellProducer.Value != null)
                {
                    int productTypeId = Convert.ToInt32(cellProductType.Value);
                    int producerId = Convert.ToInt32(cellProducer.Value);
                    if (productTypeId != 0 || producerId != 0)
                    {
                        IList<Product> products = m_Products.Where(x => (productTypeId == 0 || x.ProductTypeId == productTypeId) &&
                                                                                        (producerId == 0 || x.ProducerId == producerId)).ToList();
                        Product allProduct = new Product();
                        allProduct.Id = 0;
                        allProduct.Name = "Tất cả";
                        products.Insert(0, allProduct);
                        DataGridViewComboBoxCell cellProduct = (DataGridViewComboBoxCell)dtgBillDetail[e.ColumnIndex, e.RowIndex];
                        cellProduct.DataSource = products;
                        cellProduct.ValueMember = "Id";
                        cellProduct.DisplayMember = "Name";

                        // reset value of product column if product type or producer is changed, so the old product is not belong to new colllection of new products
                        var existingProduct = products.Where(p => p.Id == Convert.ToInt32(cellProduct.Value)).FirstOrDefault();
                        if (existingProduct == null)
                        {
                            cellProduct.Value = 0; // reset to "all product"
                        }
                    }
                    else
                    {
                        DataGridViewComboBoxCell cellProduct = (DataGridViewComboBoxCell)dtgBillDetail[e.ColumnIndex, e.RowIndex];
                        cellProduct.DataSource = m_Products;
                        cellProduct.ValueMember = "Id";
                        cellProduct.DisplayMember = "Name";
                    }
                }
            }
        }

        private void dtgBillDetail_RowEnter(object sender, DataGridViewCellEventArgs e)
        {
            if (m_EnableEvent)
            {
                var currentRow = dtgBillDetail.Rows[e.RowIndex];
                var rowNumberCell = currentRow.Cells["colRowNumber"];
                if (rowNumberCell.Value == null ||
                    rowNumberCell.Value == DBNull.Value)
                {
                    rowNumberCell.Value = e.RowIndex + 1;
                }
            }
        }

        private void dtgBillDetail_CellValueChanged(object sender, DataGridViewCellEventArgs e)
        {
            if (m_EnableEvent)
            {
                int colRowNumberIndex = dtgBillDetail.Columns["colRowNumber"].Index;
                if (e.ColumnIndex == colRowNumberIndex)
                {
                    return;
                }
                m_EnableEvent = false;
                if (dtgBillDetail[e.ColumnIndex, e.RowIndex].Value != null)
                {
                    string temp = dtgBillDetail[e.ColumnIndex, e.RowIndex].Value.ToString();
                    if (e.ColumnIndex == dtgBillDetail.Columns["colProductType"].Index ||
                        e.ColumnIndex == dtgBillDetail.Columns["colProducer"].Index ||
                        e.ColumnIndex == dtgBillDetail.Columns["colProduct"].Index)
                    {
                        int id = 0;
                        if (int.TryParse(temp, out id))
                        {
                            if (id > 0)
                            {
                                m_BillTableDataChanged = true;
                            }
                        }
                    }
                    else
                    {
                        if (!string.IsNullOrEmpty(temp))
                        {
                            m_BillTableDataChanged = true;
                        }
                    }
                }

                var currentRow = dtgBillDetail.Rows[e.RowIndex];
                if (currentRow != null)
                {
                    if (e.ColumnIndex == currentRow.Cells["colDiscount"].ColumnIndex ||
                        e.ColumnIndex == currentRow.Cells["colPrice"].ColumnIndex) // Giam gia
                    {
                        // calculate sale price
                        int discount = Convert.ToInt32(currentRow.Cells["colDiscount"].Value);
                        int price = Convert.ToInt32(currentRow.Cells["colPrice"].Value);
                        int salePrice = price - discount;
                        currentRow.Cells["colSalePrice"].Value = salePrice;
                        // calculate total price
                        int amount = Convert.ToInt32(currentRow.Cells["colAmount"].Value);
                        int total = amount * salePrice;
                        currentRow.Cells["colTotalPrice"].Value = total;
                        CalculateTotalPrice();
                    }

                    if (e.ColumnIndex == currentRow.Cells["colAmount"].ColumnIndex) // amount
                    {
                        // calculate total price
                        int amount = Convert.ToInt32(currentRow.Cells["colAmount"].Value);
                        int salePrice = Convert.ToInt32(currentRow.Cells["colSalePrice"].Value);
                        int total = amount * salePrice;
                        currentRow.Cells["colTotalPrice"].Value = total;
                        CalculateTotalPrice();
                    }

                    if (e.ColumnIndex == currentRow.Cells["colBarcode"].ColumnIndex &&
                        currentRow.Cells["colBarcode"].Value != null) //Barcode
                    {
                        string barcodeNumber = currentRow.Cells["colBarcode"].Value.ToString();
                        if (!string.IsNullOrEmpty(barcodeNumber))
                        {
                            //barcodeNumber = barcodeNumber.Substring(0, barcodeNumber.Length - 1);// ignore check sum
                            pGetProductByBarcode_Result1 product = m_ProductService.GetProductByBarcode(barcodeNumber);
                            if (product != null)
                            {
                                currentRow.Cells["colProductType"].Value = product.ProductTypeId;
                                currentRow.Cells["colProducer"].Value = product.ProducerId;
                                currentRow.Cells["colProduct"].Value = product.Id;
                                currentRow.Cells["colPrice"].Value = product.SalePrice;
                                currentRow.Cells["colAmount"].Value = 1;
                                currentRow.Cells["colDiscount"].Value = 0;
                                currentRow.Cells["colSalePrice"].Value = product.SalePrice;
                                currentRow.Cells["colTotalPrice"].Value = product.SalePrice;
                                if (product.HasWarranty)
                                {
                                    currentRow.Cells["colWarrantyTime"].Value = product.WarrantyTime;
                                }
                            }
                            else
                            {
                                MessageBox.Show("Không có sản phẩm nào tương ứng với mã vạch này", "Thông báo", MessageBoxButtons.OK, MessageBoxIcon.Error);
                            }
                        }
                    }
                }
                m_EnableEvent = true;
            }
        }

        private void dtgBillDetail_RowValidated(object sender, DataGridViewCellEventArgs e)
        {
            if (m_EnableEvent)
            {
                if (dtgBillDetail.Rows[e.RowIndex].IsNewRow) { return; }

                // Save or update order detail before move to another row.
                SaveOrUpdateBillDetail(e.RowIndex);

                btnSaveBill.Enabled = true;
                btnPrintBill.Enabled = true;
            }
        }

        private void dtgBillDetail_CellValidating(object sender, DataGridViewCellValidatingEventArgs e)
        {
            if (!m_EnableEvent) { return; }
            if (dtgBillDetail.Rows[e.RowIndex].IsNewRow) { return; }

            bool isValid = true;
            var colIndex = e.ColumnIndex;
            int rowIndex = e.RowIndex;
            object formattedValue = e.FormattedValue;
            DataGridViewRow currentRow = dtgBillDetail.Rows[e.RowIndex];

            foreach (DataGridViewCell cell in currentRow.Cells)
            {
                cell.ErrorText = "";
            }

            // validate product type
            if (colIndex == dtgBillDetail.Columns["colProductType"].Index)
            {
                if (formattedValue == null || formattedValue.ToString() == "0")
                {
                    currentRow.Cells["colProductType"].ErrorText = "Chọn loại hàng";
                    isValid = false;
                }
            }

            // validate producer
            if (colIndex == dtgBillDetail.Columns["colProducer"].Index)
            {
                if (formattedValue == null || formattedValue.ToString() == "0")
                {
                    currentRow.Cells["colProducer"].ErrorText = "Chọn nhà sản xuất";
                    isValid = false;
                }
            }

            // validate product
            if (colIndex == dtgBillDetail.Columns["colProduct"].Index)
            {
                if (formattedValue == null || formattedValue.ToString() == "0")
                {
                    currentRow.Cells["colProduct"].ErrorText = "Chọn sản phẩm";
                    isValid = false;
                }
            }

            // validate amount
            if (colIndex == dtgBillDetail.Columns["colAmount"].Index)
            {
                if (formattedValue != null)
                {
                    int amount;
                    bool parseSuccess = int.TryParse(formattedValue.ToString(), out amount);
                    if (parseSuccess)
                    {
                        if (amount <= 0)
                        {
                            currentRow.Cells["colAmount"].ErrorText = "Sai số lượng";
                            isValid = false;
                        }
                    }
                    else
                    {
                        currentRow.Cells["colAmount"].ErrorText = "Sai số lượng";
                        isValid = false;
                    }
                }
                else
                {
                    currentRow.Cells["colAmount"].ErrorText = "Nhập số lượng";
                    isValid = false;
                }
            }

            // validate price
            if (colIndex == dtgBillDetail.Columns["colPrice"].Index)
            {
                if (formattedValue != null)
                {
                    int price;
                    bool parseSuccess = int.TryParse(formattedValue.ToString(), out price);
                    if (parseSuccess)
                    {
                        if (price < 0)
                        {
                            currentRow.Cells["colPrice"].ErrorText = "Sai đơn giá";
                            isValid = false;
                        }
                    }
                    else
                    {
                        currentRow.Cells["colPrice"].ErrorText = "Sai đơn giá";
                        isValid = false;
                    }
                }
            }

            // validate discount
            if (colIndex == dtgBillDetail.Columns["colDiscount"].Index)
            {
                if (formattedValue != null && !string.IsNullOrWhiteSpace(formattedValue.ToString()))
                {
                    int discount;
                    bool parseSuccess = int.TryParse(formattedValue.ToString(), out discount);
                    if (parseSuccess)
                    {
                        if (discount < 0)
                        {
                            currentRow.Cells["colDiscount"].ErrorText = "Sai giảm giá";
                            isValid = false;
                        }
                    }
                    else
                    {
                        currentRow.Cells["colDiscount"].ErrorText = "Sai giảm giá";
                        isValid = false;
                    }
                }
            }

            // validate warranty time
            if (colIndex == dtgBillDetail.Columns["colWarrantyTime"].Index)
            {
                if (formattedValue != null && !string.IsNullOrWhiteSpace(formattedValue.ToString()))
                {
                    int warrantyTime;
                    bool parseSuccess = int.TryParse(formattedValue.ToString(), out warrantyTime);
                    if (parseSuccess)
                    {
                        if (warrantyTime <= 0)
                        {
                            currentRow.Cells["colWarrantyTime"].ErrorText = "Sai thời gian bảo hành";
                            isValid = false;
                        }
                    }
                    else
                    {
                        currentRow.Cells["colWarrantyTime"].ErrorText = "Sai thời gian bảo hành";
                        isValid = false;
                    }
                }
            }

            e.Cancel = !isValid;
        }

        private bool ValidateBillDetailRow(int rowIndex)
        {
            DataGridViewRow row = dtgBillDetail.Rows[rowIndex];

            // validate product type
            var data = row.Cells["colProductType"].Value;
            if (data == null || data.ToString() == "0")
            {
                return false;
            }

            data = row.Cells["colProducer"].Value;
            if (data == null || data.ToString() == "0")
            {
                return false;
            }

            data = row.Cells["colProduct"].Value;
            if (data == null || data.ToString() == "0")
            {
                return false;
            }

            // validate amount
            data = row.Cells["colAmount"].Value;
            if (data != null)
            {
                int amount;
                bool parseSuccess = int.TryParse(data.ToString(), out amount);
                if (parseSuccess)
                {
                    if (amount <= 0)
                    {
                        return false;
                    }
                }
                else
                {
                    return false;
                }
            }
            else
            {
                return false;
            }

            // validate price
            data = row.Cells["colPrice"].Value;
            if (data != null)
            {
                int price;
                bool parseSuccess = int.TryParse(data.ToString(), out price);
                if (parseSuccess)
                {
                    if (price < 0)
                    {
                        return false;
                    }
                }
                else
                {
                    return false;
                }
            }

            // validate discount
            data = row.Cells["colDiscount"].Value;
            if (data != null)
            {
                int discount;
                bool parseSuccess = int.TryParse(data.ToString(), out discount);
                if (parseSuccess)
                {
                    if (discount < 0)
                    {
                        return false;

                    }
                }
                else
                {
                    return false;
                }
            }

            // validate warranty time
            data = row.Cells["colWarrantyTime"].Value;
            if (data != null)
            {
                int warrantyTime;
                bool parseSuccess = int.TryParse(data.ToString(), out warrantyTime);
                if (parseSuccess)
                {
                    if (warrantyTime < 0)
                    {
                        return false;
                    }
                }
                else
                {
                    return false;
                }
            }

            return true;
        }

        private void dtgBillDetail_CellClick(object sender, DataGridViewCellEventArgs e)
        {
            if (e.RowIndex < 0) { return; }
            if (e.ColumnIndex == dtgBillDetail.Columns["colDelete"].Index)
            {
                DialogResult result = MessageBox.Show("Bạn có chắc muốn xóa chi tiết hóa đơn này", "Thông báo",
                    MessageBoxButtons.YesNo, MessageBoxIcon.Question);
                if (result == DialogResult.Yes)
                {
                    var currentRow = dtgBillDetail.Rows[e.RowIndex];
                    var temp = currentRow.Cells["colBillDetailId"].Value;
                    if (temp != null)
                    {
                        int billDetailId = 0;
                        if (int.TryParse(temp.ToString(), out billDetailId))
                        {
                            DeleteBillDetail(billDetailId, e.RowIndex);
                        }
                    }
                    else // row haven't save, just delete on grid
                    {
                        // Delete row in data grid
                        dtgBillDetail.Rows.RemoveAt(e.RowIndex);

                        // Update total price
                        CalculateTotalPrice();
                    }
                    btnPaid.Enabled = false;
                }
            }
        }

        private void dtgBillDetail_Enter(object sender, EventArgs e)
        {
            if (dtgBillDetail.Rows.Count > 0)
            {
                dtgBillDetail.CurrentCell = dtgBillDetail.Rows[dtgBillDetail.Rows.Count - 1].Cells["colBarcode"];
            }
        }

        private void dtgBillDetail_CurrentCellDirtyStateChanged(object sender, EventArgs e)
        {
            if (dtgBillDetail.IsCurrentCellDirty)
            {
                int productId = Convert.ToInt32(dtgBillDetail.CurrentRow.Cells["colProduct"].Value);
                if (productId > 0)
                {
                    dtgBillDetail.CommitEdit(DataGridViewDataErrorContexts.Commit);
                }
            }
        }
        #endregion dtgDetail Events

        #region Other Events
        private void btnCreateBill_Click(object sender, EventArgs e)
        {
            if (m_BillTableDataChanged)
            {
                SaveOrUpdateBillDetail(dtgBillDetail.CurrentRow.Index);
                m_BillTableDataChanged = false;
            }
            ClearBillData();
            CreateNewBill();
        }

        private void btnSaveBill_Click(object sender, EventArgs e)
        {
            try
            {
                SaveBillAndDetail();
                ReloadCustomerList();
            }
            catch (Exception ex)
            {
                MyLogger.LogException("Lỗi xảy ra khi lưu hóa đơn: ", ex);
                ForceCloseWhenError();
            }
        }

        private void cboProduct_SelectedIndexChanged(object sender, EventArgs e)
        {
            ComboBox cbo = sender as ComboBox;
            if (m_EnableProductChangedEvent && dtgBillDetail.CurrentCell != null
                && cbo.SelectedIndex > -1 && cbo.SelectedValue is int //Combobox should complete
                && dtgBillDetail.CurrentCell.ColumnIndex == dtgBillDetail.Columns["colProduct"].Index)
            {
                m_EnableEvent = false;
                // Set value for current row
                int productId = Convert.ToInt32(cbo.SelectedValue);
                if (productId != 0)
                {
                    Product product = m_Products.Where(x => x.Id == productId).FirstOrDefault();
                    dtgBillDetail.CurrentRow.Cells["colProductType"].Value = product.ProductTypeId;
                    dtgBillDetail.CurrentRow.Cells["colProducer"].Value = product.ProducerId;
                    dtgBillDetail.CurrentRow.Cells["colProduct"].Value = product.Id;
                    dtgBillDetail.CurrentRow.Cells["colPrice"].Value = product.SalePrice;
                    dtgBillDetail.CurrentRow.Cells["colAmount"].Value = 1;
                    dtgBillDetail.CurrentRow.Cells["colDiscount"].Value = 0;
                    dtgBillDetail.CurrentRow.Cells["colSalePrice"].Value = product.SalePrice;
                    dtgBillDetail.CurrentRow.Cells["colTotalPrice"].Value = product.SalePrice;
                    dtgBillDetail.CurrentRow.Cells["colBarcode"].Value = product.Barcode;
                    if (product.HasWarranty)
                    {
                        dtgBillDetail.CurrentRow.Cells["colWarrantyTime"].Value = product.WarrantyTime;
                    }
                    else
                    {
                        dtgBillDetail.CurrentRow.Cells["colWarrantyTime"].Value = null;
                    }
                    m_BillTableDataChanged = true;
                }
                else // User choose "Tat ca" product, then reset all columns' value
                {
                    dtgBillDetail.CurrentRow.Cells["colPrice"].Value = null;
                    dtgBillDetail.CurrentRow.Cells["colAmount"].Value = null;
                    dtgBillDetail.CurrentRow.Cells["colDiscount"].Value = null;
                    dtgBillDetail.CurrentRow.Cells["colSalePrice"].Value = null;
                    dtgBillDetail.CurrentRow.Cells["colTotalPrice"].Value = null;
                    dtgBillDetail.CurrentRow.Cells["colBarcode"].Value = null;
                    dtgBillDetail.CurrentRow.Cells["colWarrantyTime"].Value = null;
                    m_BillTableDataChanged = false;
                }
                m_EnableEvent = true;
            }
        }

        private void cboKhachHang_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (m_EnableEvent && cboKhachHang.SelectedValue != null)
            {
                // Save data
                if (dtgBillDetail.CurrentRow != null && !dtgBillDetail.CurrentRow.IsNewRow) // Update not printed bill
                {
                    SaveOrUpdateBillDetail(dtgBillDetail.CurrentRow.Index);
                }
                ClearError();
                EnableEvents(false);
                int billId = Convert.ToInt32(cboKhachHang.SelectedValue);
                if (billId > 0)
                {
                    ShowBillDetail(billId);
                }
                EnableBillDetailControl(true);
                EnableEvents(true);
            }
        }

        private void ClearError()
        {
            errorProvider1.SetError(txtCustomerName, "");
        }

        private void btnDeleteBill_Click(object sender, EventArgs e)
        {
            DialogResult result = MessageBox.Show("Bạn có chắc muốn xóa hóa đơn này?", "Thông báo",
                   MessageBoxButtons.YesNo, MessageBoxIcon.Question);
            if (result == DialogResult.Yes)
            {
                try
                {
                    bool deleteSuccess = m_BillService.DeleteBillAndDetail(m_currentBill.Id);
                    if (deleteSuccess)
                    {
                        ReloadCustomerList(true);
                        btnSaveBill.Enabled = false;
                        btnDeleteBill.Enabled = false;
                    }
                }
                catch (Exception ex)
                {
                    MyLogger.LogException("Lỗi xả ra khi xóa hóa đơn", ex);
                    ForceCloseWhenError();
                }
            }
        }

        private void btnAddProduct_Click(object sender, EventArgs e)
        {
            FormAddProduct frm = new FormAddProduct();
            frm.ShowDialog();

            //reload all products list if add product successfully
            if (frm.Saved)
            {
                m_Products = m_ProductService.GetProducts();
                Product allProduct = new Product();
                allProduct.Id = 0;
                allProduct.Name = "Tất cả";
                m_Products.Insert(0, allProduct);
            }
        }

        private void EnableBillDetailControl(bool enable)
        {
            dtgBillDetail.Enabled = enable;
            txtCustomerName.ReadOnly = !enable;
            txtPhoneNumber.ReadOnly = !enable;
            txtAddress.ReadOnly = !enable;
        }

        private void btnPrintBill_Click(object sender, EventArgs e)
        {
            try
            {
                bool saveBillSuccess = SaveBillAndDetail();
                if (saveBillSuccess)
                {
                    // Update amount of product and update remaining amount of product input detail
                    if (m_currentBill != null && m_currentBill.Id > 0)
                    {
                        Print();
                        // Update status inform that the bill ready for paid
                        m_currentBill.IsReadyPaid = true;
                        m_BillService.Update(m_currentBill);
                        btnPaid.Enabled = true;
                    }
                }
            }
            catch (Exception ex)
            {
                MyLogger.LogException("Lỗi xảy ra khi in hóa đơn: ", ex);
                ForceCloseWhenError();
            }
        }

        private void btnPaid_Click(object sender, EventArgs e)
        {
            try
            {
                // Update amount of product and update remaining amount of product input detail
                if (m_currentBill != null && m_currentBill.Id > 0)
                {
                    bool success = m_BillService.Sale(m_currentBill.Id);
                    if (success)
                    {
                        m_currentBill.IsPrinted = true;
                        UpdateCustomerList();
                        EnableBillDetailControl(false);
                        btnSaveBill.Enabled = false;
                        btnPrintBill.Enabled = false;
                        btnDeleteBill.Enabled = false;
                        btnCreateBill.Enabled = true;
                        btnPaid.Enabled = false;
                    }
                    else
                    {
                        MessageBox.Show("Có lổi xảy ra nên hóa đơn chưa được lưu", "Thông báo",
                            MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                }
            }
            catch (Exception ex)
            {
                MyLogger.LogException("Lỗi xảy ra khi thanh toán hóa đơn: ", ex);
                ForceCloseWhenError();
            }
        }

        private void txtGivenMoney_Leave(object sender, EventArgs e)
        {
            if (!string.IsNullOrEmpty(this.txtGivenMoney.Text))
            {
                int price = Convert.ToInt32(this.txtGivenMoney.Text);
                price = price * 1000;
                this.txtGivenMoney.Text = price.ToMoney();
            }
        }

        private void txtGivenMoney_Enter(object sender, EventArgs e)
        {
            if (this.txtGivenMoney.Text != "")
            {
                int price = this.txtGivenMoney.Text.ToNumberFromMoney();
                price = price / 1000;
                this.txtGivenMoney.Text = price.ToString();
            }
        }

        private void txtGivenMoney_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (!char.IsControl(e.KeyChar)
               && !char.IsDigit(e.KeyChar) || e.KeyChar == 13)
            {
                e.Handled = true;
                if (e.KeyChar == 13 && lblTotalPrice.Text != "" && txtGivenMoney.Text != "")
                {
                    // calculate return money
                    int totalPrice = lblTotalPrice.Text.ToNumberFromMoney();
                    int givenMoney = Convert.ToInt32(txtGivenMoney.Text);
                    givenMoney = givenMoney * 1000;
                    int returnMoney = givenMoney - totalPrice;
                    lblReturnMoney.Text = returnMoney.ToMoney();
                }
            }
        }
        #endregion Other Events
        #endregion Events

        #region Methods
        private void EnableEvents(bool enabled)
        {
            m_EnableProductTypeChangedEvent = enabled;
            m_EnableProducerChangedEvent = enabled;
            m_EnableProductChangedEvent = enabled;
            m_EnableEvent = enabled;
        }

        private void CreateNewBill()
        {
            m_currentBill = new Bill();
            m_currentBill.Id = 0;
            m_currentBill.IsPrinted = false;
            m_currentBill.IsReadyPaid = false;
            m_currentBill.SaleTime = DateTime.Now;

            pGetNextBillIdAndIndex_Result nextBillIdAndIndex = m_BillService.GetNextIndexInDay();
            m_currentBill.DayIndex = nextBillIdAndIndex.NextBillIndex.Value;
            lblCreateTime.Text = m_currentBill.SaleTime.ToString("dd/MM/yyyy hh:mm");
            this.lblTotalPrice.Text = "0 Đ";
            this.lblReturnMoney.Text = "0 Đ";
            txtGivenMoney.Text = "";

            EnableBillDetailControl(true);
            txtCustomerName.Text = GenNextCustomerName();
            dtgBillDetail.Select();
            btnPaid.Enabled = false;
            m_EnableEvent = false;
            cboKhachHang.SelectedIndex = 0;
            m_EnableEvent = true;
        }

        private List<Bill> GetActiveBills()
        {
            List<Bill> activeBills = m_BillService.GetActiveBills();
            Bill emptyBill = new Bill();
            emptyBill.Id = 0;
            emptyBill.CustomerName = "Chọn khách hàng";
            activeBills.Insert(0, emptyBill);
            return activeBills;
        }

        private void SetupAutoCompleteDropdownInGrid(ComboBox cbo)
        {
            cbo.DropDownStyle = ComboBoxStyle.DropDown;
            cbo.AutoCompleteMode = AutoCompleteMode.SuggestAppend;
            cbo.AutoCompleteSource = AutoCompleteSource.ListItems;
            cbo.KeyDown -= new KeyEventHandler(cbo_KeyDown);
            cbo.KeyDown += new KeyEventHandler(cbo_KeyDown);
        }

        private void cbo_KeyDown(object sender, KeyEventArgs e)
        {
            ComboBox cbo = sender as ComboBox;
            if (cbo.DroppedDown)
            {
                cbo.DroppedDown = false;
            }
        }

        private void GetCustomerInformation()
        {
            if (!string.IsNullOrEmpty(txtCustomerName.Text))
            {
                m_currentBill.CustomerName = txtCustomerName.Text;
            }
            if (!string.IsNullOrEmpty(txtPhoneNumber.Text))
            {
                m_currentBill.CustomerPhone = Convert.ToInt32(txtPhoneNumber.Text);
            }
            m_currentBill.CustomerAddress = txtAddress.Text;
        }

        private void AddBill()
        {
            // create new bill
            try
            {
                GetCustomerInformation();
                m_BillService.Add(m_currentBill);
            }
            catch (Exception ex)
            {
                MyLogger.LogException("Lỗi xảy ra khi thêm hóa đơn: " + ex.Message, ex);
                ForceCloseWhenError();
            }
        }

        private bool SaveBillAndDetail()
        {
            bool result = true;
            try
            {
                // Check total price > 0, just print bill has price > 0
                int totalPrice = lblTotalPrice.Text.ToNumberFromMoney();
                if (totalPrice >= 0)
                {
                    // Save bill
                    FillCustomerName();
                    // If bill have not saved because bill info is not correct, save bill & all bill detail
                    if (m_currentBill.Id == 0)
                    {
                        AddBill();

                        if (m_currentBill.Id > 0)
                        {
                            foreach (DataGridViewRow row in dtgBillDetail.Rows)
                            {
                                if (!row.IsNewRow)
                                {
                                    AddBillDetail(row);
                                }
                            }
                        }
                    }
                    else if (m_currentBill.Id > 0)
                    {
                        // Update bill information
                        UpdateBill();

                        foreach (DataGridViewRow row in dtgBillDetail.Rows)
                        {
                            if (!row.IsNewRow)
                            {
                                int billDetailId = Convert.ToInt32(row.Cells["colBillDetailId"].Value);
                                if (billDetailId == 0)
                                {
                                    AddBillDetail(row);
                                }
                            }
                        }
                    }
                    else
                    {
                        result = false;
                        ForceCloseWhenError();
                    }
                }
                else
                {
                    MessageBox.Show("Hóa đơn phải có số tiền > 0", "Thông báo", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    result = false;
                }
            }
            catch (Exception ex)
            {
                MyLogger.LogException("Lỗi xảy ra ở màn hình quản lý hóa đơn", ex);
                result = false;
                ForceCloseWhenError();
            }
            return result;
        }

        private void ForceCloseWhenError()
        {
            MessageBox.Show("Dữ liệu bị sai, vui lòng mở lại màn hình quản lý hóa đơn", "Thông báo",
                        MessageBoxButtons.OK, MessageBoxIcon.Error);
            this.Close();
        }

        private void AddBillDetail(DataGridViewRow row)
        {
            try
            {
                // create bill detail
                BillDetail billDetail = new BillDetail();
                billDetail.BillId = m_currentBill.Id;
                billDetail.ProductId = Convert.ToInt32(row.Cells["colProduct"].Value);
                billDetail.ProductPrice = Convert.ToInt32(row.Cells["colPrice"].Value);
                billDetail.Amount = Convert.ToInt32(row.Cells["colAmount"].Value);
                billDetail.SalePrice = Convert.ToInt32(row.Cells["colSalePrice"].Value);
                billDetail.WarrantyTime = Convert.ToInt16(row.Cells["colWarrantyTime"].Value);
                if (billDetail.BillId > 0 && billDetail.ProductId > 0 && billDetail.Amount > 0)
                {
                    m_BillDetailService.Add(billDetail);
                }
                row.Cells["colBillDetailId"].Value = billDetail.Id;
            }
            catch (Exception ex)
            {
                MyLogger.LogException("Lỗi xảy ra khi thêm chi tiết hóa đơn: " + ex.Message, ex);
                ForceCloseWhenError();
            }
        }

        private void UpdateBill()
        {
            try
            {
                GetCustomerInformation();
                m_BillService.Update(m_currentBill);
            }
            catch (Exception ex)
            {
                MyLogger.LogException("Lỗi xảy ra khi cập nhật hóa đơn: " + ex.Message, ex);
                ForceCloseWhenError();
            }
        }

        private void UpdateBillDetail(DataGridViewRow row)
        {
            try
            {
                BillDetail billDetail = new BillDetail();
                billDetail.Id = Convert.ToInt32(row.Cells["colBillDetailId"].Value);
                billDetail.BillId = m_currentBill.Id;
                billDetail.ProductId = Convert.ToInt32(row.Cells["colProduct"].Value);
                billDetail.ProductPrice = Convert.ToInt32(row.Cells["colPrice"].Value);
                billDetail.Amount = Convert.ToInt32(row.Cells["colAmount"].Value);
                billDetail.SalePrice = Convert.ToInt32(row.Cells["colSalePrice"].Value);
                billDetail.WarrantyTime = Convert.ToInt16(row.Cells["colWarrantyTime"].Value);
                m_BillDetailService.Update(billDetail);
            }
            catch (Exception ex)
            {
                MyLogger.LogException("Lỗi xảy ra khi cập nhật chi tiết hóa đơn: " + ex.Message, ex);
                ForceCloseWhenError();
            }
        }

        private void SaveOrUpdateBillDetail(int rowNumber)
        {
            if (m_BillTableDataChanged)
            {
                bool isValid = ValidateBillDetailRow(rowNumber);
                if (isValid)
                {
                    try
                    {
                        var row = dtgBillDetail.Rows[rowNumber];
                        int productId = 0;
                        bool parseSuccess = int.TryParse(row.Cells["colProduct"].Value.ToString(), out productId);
                        if (parseSuccess && productId > 0)
                        {
                            if (row.Cells["colBillDetailId"].Value != null)  // update bill detail
                            {
                                UpdateBillDetail(row);
                            }
                            else // add bill detail
                            {
                                bool addedBill = false;
                                if (m_currentBill.Id == 0)
                                {
                                    FillCustomerName();
                                    AddBill();
                                    addedBill = true;
                                }
                                if (m_currentBill.Id > 0)
                                {
                                    AddBillDetail(row);
                                }
                                if (addedBill)
                                {
                                    ReloadCustomerList(false);
                                }
                            }
                            CalculateTotalPrice();
                            btnPaid.Enabled = false;

                            // Update total money of current customer
                            UpdateTotalMoneyOfCurrentCustomer();
                            m_BillTableDataChanged = false;
                        }
                    }
                    catch (Exception ex)
                    {
                        MyLogger.LogException("Lỗi xảy ra khi thêm/cập nhật chi tiết hóa đơn", ex);
                        ForceCloseWhenError();
                    }
                }
                else
                {
                    // No thing to do, just don't save the bill detail
                    //MessageBox.Show("Loi");
                }
            }
        }

        private void UpdateTotalMoneyOfCurrentCustomer()
        {
            int totalPrice = 0;
            foreach (DataGridViewRow row in dtgBillDetail.Rows)
            {
                if (!row.IsNewRow && Convert.ToInt32(row.Cells["colProduct"].Value) > 0)
                {
                    totalPrice += Convert.ToInt32(row.Cells["colTotalPrice"].Value);
                }
            }

            foreach (Bill item in m_ActiveBills)
            {
                if (item.Id == m_currentBill.Id)
                {
                    item.TotalPrice = totalPrice;
                    break;
                }
            }

            m_EnableEvent = false;
            cboKhachHang.DataSource = null;
            cboKhachHang.Items.Clear();
            cboKhachHang.DataSource = m_ActiveBills;
            cboKhachHang.ValueMember = "Id";
            cboKhachHang.DisplayMember = "TotalMoney";
            m_EnableEvent = true;
        }

        private void AddItemsToBillDetailGrid(List<pGetBIllDetailByBillId_Result> billDetails)
        {
            dtgBillDetail.Rows.Clear(); // Clear old data
            int i = 0;
            foreach (pGetBIllDetailByBillId_Result billDetail in billDetails)
            {
                dtgBillDetail.Rows.Add(1);
                DataGridViewRow row = dtgBillDetail.Rows[i];
                row.Cells["colRowNumber"].Value = billDetail.RowNumber;
                row.Cells["colProductType"].Value = billDetail.ProductTypeId;
                row.Cells["colProducer"].Value = billDetail.ProducerId;
                row.Cells["colProduct"].Value = billDetail.ProductId;
                row.Cells["colBarcode"].Value = billDetail.Barcode;
                row.Cells["colPrice"].Value = billDetail.ProductPrice;
                row.Cells["colDiscount"].Value = billDetail.Discount;
                row.Cells["colSalePrice"].Value = billDetail.SalePrice;
                row.Cells["colAmount"].Value = billDetail.Amount;
                row.Cells["colTotalPrice"].Value = billDetail.TotalPrice;
                row.Cells["colWarrantyTime"].Value = billDetail.WarrantyTime;
                row.Cells["colBillDetailId"].Value = billDetail.Id;
                i++;
            }
        }

        private void ShowBillDetail(int billId)
        {
            m_currentBill = m_BillService.GetById(billId);
            txtCustomerName.Text = m_currentBill.CustomerName;
            txtAddress.Text = m_currentBill.CustomerAddress;
            txtPhoneNumber.Text = m_currentBill.CustomerPhone.ToString();
            lblCreateTime.Text = m_currentBill.SaleTime.ToString(Formats.DateTimeFormat);
            dtgBillDetail.AutoGenerateColumns = false;
            List<pGetBIllDetailByBillId_Result> billDetails = m_BillDetailService.GetBillDetailByBillId(billId);
            AddItemsToBillDetailGrid(billDetails);
            CalculateTotalPrice();
            lblReturnMoney.Text = "0 Đ";
            txtGivenMoney.Text = "";
            m_BillTableDataChanged = false;
            if (billDetails.Count > 0)
            {
                btnSaveBill.Enabled = true;
                btnPrintBill.Enabled = true;
            }
            btnPaid.Enabled = m_currentBill.IsReadyPaid.HasValue ? m_currentBill.IsReadyPaid.Value : false;
        }

        private void FillCustomerName()
        {
            if (string.IsNullOrWhiteSpace(txtCustomerName.Text))
            {
                txtCustomerName.Text = GenNextCustomerName();
            }
        }

        private void CalculateTotalPrice()
        {
            int totalPrice = 0;
            foreach (DataGridViewRow row in this.dtgBillDetail.Rows)
            {
                var temp = row.Cells["colTotalPrice"].Value;
                if (temp != null)
                {
                    int itemPrice = 0;
                    if (int.TryParse(temp.ToString(), out itemPrice))
                    {
                        totalPrice += itemPrice;
                    }
                }
            }

            lblTotalPrice.Text = totalPrice.ToMoney();
        }

        private bool IsEmptyDataGridView()
        {
            return dtgBillDetail.Rows.Count == 0 || (dtgBillDetail.Rows.Count == 1 && dtgBillDetail.Rows[0].IsNewRow);
        }

        private void ReloadCustomerList(bool reloadGrid = false)
        {
            EnableEvents(false);
            m_ActiveBills = GetActiveBills();
            cboKhachHang.DataSource = m_ActiveBills;
            if (m_ActiveBills.Count > 1)
            {
                cboKhachHang.SelectedIndex = 1;
                if (reloadGrid)
                {
                    ShowBillDetail(m_ActiveBills[1].Id);
                }
                btnDeleteBill.Enabled = true;
            }
            else
            {
                ClearBillData();
                CreateNewBill();
                btnDeleteBill.Enabled = false;
            }
            btnCreateBill.Enabled = true;
            EnableEvents(true);
        }

        private void UpdateCustomerList()
        {
            EnableEvents(false);
            m_ActiveBills = GetActiveBills();
            cboKhachHang.DataSource = m_ActiveBills;
            EnableEvents(true);
        }

        private void DeleteBillDetail(int billDetailId, int rowIndex)
        {
            try
            {
                // Delete bill detail
                m_BillDetailService.Delete(billDetailId);

                // Delete row in data grid
                dtgBillDetail.Rows.RemoveAt(rowIndex);

                // Update total price
                CalculateTotalPrice();

                // Check whether bill have any bill detail, if delete all, ask user want to delete bill as well.
                if (IsEmptyDataGridView())
                {
                    DialogResult result = MessageBox.Show("Bạn đã xóa hết chi tiết hóa đơn, bạn có muốn xóa hóa đơn này?", "Thông báo",
                        MessageBoxButtons.YesNo, MessageBoxIcon.Question);
                    if (result == DialogResult.Yes)
                    {
                        bool deletedSuccess = m_BillService.Delete(m_currentBill.Id);
                        if (deletedSuccess)
                        {
                            ReloadCustomerList(true);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                MyLogger.LogException("Lỗi xảy ra khi xóa chi tiết hóa đơn", ex);
                ForceCloseWhenError();
            }
        }

        private void ClearBillData()
        {
            this.txtAddress.Text = "";
            this.txtCustomerName.Text = "";
            this.txtPhoneNumber.Text = "";
            EnableEvents(false);
            this.dtgBillDetail.DataSource = null; // remove all detail
            this.dtgBillDetail.Rows.Clear();
            this.dtgBillDetail.Invalidate();
            EnableEvents(true);
            this.dtgBillDetail.Focus();
        }

        private string GenNextCustomerName()
        {
            string customerName = "";
            if (cboKhachHang.Items.Count > 1)
            {
                Bill lastBill = cboKhachHang.Items[1] as Bill;
                if (lastBill != null)
                {
                    string lastName = lastBill.CustomerName;
                    if (lastName.Contains("Khách hàng"))
                    {
                        int cusIndex = 0;
                        bool parseSuccess = int.TryParse(lastName.Substring(lastName.Length - 1), out cusIndex);
                        if (parseSuccess)
                        {
                            customerName = "Khách hàng " + (cusIndex + 1).ToString();
                        }
                        else
                        {
                            customerName = "Khách hàng " + cboKhachHang.Items.Count;
                        }
                    }
                    else
                    {
                        customerName = "Khách hàng " + cboKhachHang.Items.Count;
                    }
                }
                else
                {
                    customerName = "Khách hàng " + cboKhachHang.Items.Count;
                }
            }
            else
            {
                customerName = "Khách hàng 1";
            }
            return customerName;
        }

        public int FindLastRow()
        {
            int lastColumn = dtgBillDetail.Rows.Count - 1;
            for (int i = 0; i < dtgBillDetail.Rows.Count; i++)
            {
                var row = dtgBillDetail.Rows[i];
                int productId = Convert.ToInt32(row.Cells["colProduct"].Value);
                if (productId == 0)
                {
                    lastColumn = i;
                    break;
                }
            }
            return lastColumn;
        }

        #region Print Bill
        private void SetUpPrint()
        {
            List<string> printColumns = new List<string>();
            printColumns.Add("colProduct");
            printColumns.Add("colAmount");
            printColumns.Add("colTotalPrice");
            printColumns.Add("colWarrantyTime");

            List<float> columnsWidth = new List<float>();
            columnsWidth.Add(150);
            columnsWidth.Add(20);
            columnsWidth.Add(80);
            columnsWidth.Add(25);
            string printerName = ConfigurationManager.AppSettings["BillPrinterName"];
            string title = FormMain.s_Setting.ShopNamePrefix + " " + FormMain.s_Setting.ShopName;
            printing = new PrintDGV(dtgBillDetail, printColumns, columnsWidth, title, printerName);
        }

        private void SetUpPrintBillHeaderAndFooter()
        {
            //Headers
            PrintText printText;
            List<PrintText> headerRegionTexts = new List<PrintText>();
            if (FormMain.s_Setting != null)
            {
                string namePrefix = FormMain.s_Setting.ShopNamePrefix;
                string name = FormMain.s_Setting.ShopName;
                string address = FormMain.s_Setting.ShopAddress;
                string phoneNumber = FormMain.s_Setting.ShopPhoneNumber;

                printText = new PrintText(namePrefix, new Font("Arial", 9), StringAlignment.Near);
                headerRegionTexts.Add(printText);

                printText = new PrintText(name, new Font("Arial", 20, FontStyle.Italic | FontStyle.Bold), StringAlignment.Center);
                headerRegionTexts.Add(printText);

                printText = new PrintText("ĐC: " + address, new Font("Arial", 9), StringAlignment.Near);
                headerRegionTexts.Add(printText);

                printText = new PrintText("ĐT: " + phoneNumber, new Font("Arial", 9), StringAlignment.Near);
                headerRegionTexts.Add(printText);
            }

            string tmpText;
            tmpText = "Hóa đơn " + m_currentBill.Id.ToString() + " - " +
                        m_currentBill.SaleTime.ToString("dd/MM/yyyy hh:mm");
            printText = new PrintText(tmpText);
            headerRegionTexts.Add(printText);

            //printText = new PrintText("Khách hàng: " + m_currentBill.CustomerName, new Font("Arial", 9), StringAlignment.Near);
            //headerRegionTexts.Add(printText);

            //if (!string.IsNullOrEmpty(m_currentBill.CustomerAddress.ToString()))
            //{
            //    printText = new PrintText("ĐC: " + m_currentBill.CustomerAddress, new Font("Arial", 9), StringAlignment.Near);
            //    headerRegionTexts.Add(printText);
            //}

            //if (m_currentBill.CustomerPhone != null && !string.IsNullOrEmpty(m_currentBill.CustomerPhone.ToString()))
            //{
            //    printText = new PrintText("ĐT: " + m_currentBill.CustomerPhone, new Font("Arial", 9), StringAlignment.Near);
            //    headerRegionTexts.Add(printText);
            //}

            printing.headerRegionTexts = headerRegionTexts;

            //Sum Region
            List<PrintText> sumRegionTexts = new List<PrintText>();
            printText = new PrintText("Tổng cộng: " + lblTotalPrice.Text, new Font("Arial", 10, FontStyle.Bold), StringAlignment.Far);
            sumRegionTexts.Add(printText);
            printing.sumRegionTexts = sumRegionTexts;

            //Footer
            List<PrintText> footerRegionTexts = new List<PrintText>();
            printText = new PrintText("********************", new Font("Arial", 9, FontStyle.Bold), StringAlignment.Center);
            footerRegionTexts.Add(printText);

            printText = new PrintText("Quý khách vui lòng giữ lại hóa đơn để được", new Font("Arial", 9, FontStyle.Bold | FontStyle.Italic), StringAlignment.Near);
            footerRegionTexts.Add(printText);

            printText = new PrintText("bảo hành", new Font("Arial", 9, FontStyle.Bold | FontStyle.Italic), StringAlignment.Near);
            footerRegionTexts.Add(printText);

            printText = new PrintText("\n", new Font("Arial", 9, FontStyle.Bold | FontStyle.Italic), StringAlignment.Near);
            footerRegionTexts.Add(printText);

            printText = new PrintText("Cảm ơn quý khách", new Font("Arial", 9, FontStyle.Bold | FontStyle.Italic), StringAlignment.Center);
            footerRegionTexts.Add(printText);

            printText = new PrintText("Hẹn gặp lại", new Font("Arial", 9, FontStyle.Bold | FontStyle.Italic), StringAlignment.Center);
            footerRegionTexts.Add(printText);

            printing.footerRegionTexts = footerRegionTexts;
        }

        private void Print()
        {
            try
            {
                SetUpPrintBillHeaderAndFooter();
                printing.Print();
            }
            catch (Exception ex)
            {
                MyLogger.LogException("Lỗi xảy ra khi in", ex);
                MessageBox.Show("Có lỗi xảy ra: " + ex.Message, "Thông báo", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
        #endregion Print Bill

        #endregion Methods
    }
}
